﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using SlimDX.XInput;
using WiimoteLib;
using System.Threading;

namespace GamepadDriver
{
	public class Program
	{
		#region Constants

		//public const int MONITOR_ON = -1;
		//public const int MONITOR_OFF = 2;
		//public const int WM_MOUSEMOVE = 0x0200;
		//public const int WM_SETCURSOR = 0x0020;
		//public const int WM_SYSCOMMAND = 0x0112;
		//public const int SC_MONITORPOWER = 0xF170;
		//public const UInt32 ES_CONTINUOUS = 0x80000000;

		private const int THRESHOLD = 5;

		#endregion

		#region Variables

		private static bool _done = false;

		private static Point3 _origin;
		private static Point3 _delta;
		private static bool _leftDown = false;
		private static bool _rightDown = false;
		private static bool _wheelDown = false;
		private static WiimoteCollection _wiimotes = new WiimoteCollection();

		#endregion

		#region Methods

		public static void Main(string[] args)
		{
			//var vibration = new Vibration();

			//SlimDX.DirectSound.DirectSoundCapture captureDevice = new SlimDX.DirectSound.DirectSoundCapture();
			//SlimDX.Multimedia.WaveFormat waveFormat = new SlimDX.Multimedia.WaveFormat();
			//waveFormat.FormatTag = SlimDX.Multimedia.WaveFormatTag.IeeeFloat;
			//waveFormat.BitsPerSample = 32;
			//waveFormat.BlockAlignment = (short)(waveFormat.BitsPerSample / 8);
			//waveFormat.Channels = 1;
			//waveFormat.SamplesPerSecond = 44100;
			//waveFormat.AverageBytesPerSecond = waveFormat.SamplesPerSecond * waveFormat.BlockAlignment * waveFormat.Channels;


			
			//SlimDX.DirectSound.CaptureBufferDescription bufferDescription = new SlimDX.DirectSound.CaptureBufferDescription();
			//bufferDescription.BufferBytes = 8192;
			//bufferDescription.Format = waveFormat;
			//bufferDescription.WaveMapped = false;

			//SlimDX.DirectSound.CaptureBuffer buffer = new SlimDX.DirectSound.CaptureBuffer(captureDevice, bufferDescription);
			//buffer.Start(true);

			//float[] sample = new float[8192 / sizeof(float)];

			var ctrl = new EventWrappedController(UserIndex.One);
			Console.WriteLine("Connected: {0}", ctrl._controller.IsConnected);

			ctrl.Map(GamepadButtonFlags.X, state => MouseController.UseButton(MouseButton.Left, state));
			ctrl.Map(GamepadButtonFlags.A, state => MouseController.UseButton(MouseButton.Right, state));
			ctrl.Map(GamepadThumb.Left, amount => MouseController.MoveBy(amount));
			/*
			ctrl.Map(GamepadThumb.Right, amount =>
				{
					// Map LeftTrigger's 0-255 to LeftMotorSpeed's 0-65535
					vibration.LeftMotorSpeed = (ushort)((amount.X + 1) * 32768);
					vibration.RightMotorSpeed = (ushort)((amount.Y + 1) * 32768);
					ctrl._controller.SetVibration(vibration);
				});
			*/

			WiimoteFactory.Initialize();
			var wiimote = WiimoteFactory.GetWiimote(UserIndex.One);
			wiimote.Map(WiimoteButton.Home, ws => _done = true);

			while (!_done)
			{
				if (Console.KeyAvailable)
				{
					var key = Console.ReadKey();
					if (key.Key == ConsoleKey.Escape)
					{
						_done = true;
					}
				}

				/*
				var result = buffer.Read(sample, 0, true);
				Console.SetCursorPosition(0, 3);
				for (int index = 0; index < 32; index++)
				{
					Console.Write("{0}|", (ushort)Math.Abs(sample[index] * 65536));
					ctrl._controller.SetVibration(new Vibration() { RightMotorSpeed = (ushort)Math.Abs(sample[index] * 65536) });
				}
				Console.WriteLine();
				*/

				/*var gamepad = ctrl._controller.GetState().Gamepad;
				if (DateTime.Now >= nextMove)
				{
					var addTicks = sensitivity - sensitivity * 0.9 * Math.Abs(gamepad.GetLeftThumb().Length());
					
					MouseController.MoveBy(gamepad.GetLeftThumb().InvertTheYAxis());
					nextMove = nextMove.AddTicks((long)addTicks);
				}*/

				if (ctrl._controller.IsConnected)
				{
					ctrl.Update();
				}
			}

			if (ctrl._controller.IsConnected)
			{
				ctrl._controller.SetVibration(new Vibration() { LeftMotorSpeed = 0, RightMotorSpeed = 0 });
			}
			//buffer.Stop();
			//buffer.Dispose();
			//captureDevice.Dispose();

			WiimoteFactory.Destroy();
		}

		public static UInt32 MakeDWORD(ushort hiWord, ushort loWord)
		{
			return (((UInt32)hiWord) << 16) | loWord;
		}

		#region External Methods

		[DllImport("user32.dll")]
		static extern IntPtr GetMessageExtraInfo();

		[DllImport("user32.dll", SetLastError = true)]
		[return: MarshalAs(UnmanagedType.Bool)]
		public static extern bool PostMessage(IntPtr hWnd, UInt32 msg, int wParam, int lParam);

		[DllImport("user32.dll")]
		public static extern int SendMessage(IntPtr hWnd, UInt32 msg, int wParam, int lParam);

		[DllImport("user32.dll")]
		public static extern IntPtr GetDesktopWindow();

		#endregion

		#endregion
	}
}